import re
from datetime import datetime
from pathlib import Path, PurePath
import csv
from sys import argv

#
import pydash

# ================common区================
DEBUG = Path("DEBUG").exists() and Path("DEBUG").is_file()
SUFFIXES_VIDEO = {".mp4", ".mkv", ".avi", ".mov", ".fill", ".miss"}


def filename_suffix(filename: str):
    return ".{}".format(filename.split(".")[-1]).lower()


def filename_stem(filename: str):
    return ".".join(filename.split(".")[:-1])


def write_csv(file_path: Path, data):
    with open(file_path, "w", newline="", encoding="utf-8-sig") as file:
        writer = csv.writer(file)
        writer.writerows(data)


# ================服务器运行侧================
def datetime_from_filepath(text: str):
    text = re.search(r"\d+年\d+月", text).group()
    return datetime.strptime(text, "%Y年%m月").strftime("%Y-%m")


def output_video_list(source_root: Path, year_range=()):
    if len(year_range) == 0:
        targeted_dirs = [
            i
            for i in source_root.glob("*")
            if i.is_dir() and (year_range[0] <= int(datetime_from_filepath(i.name).split("-")[0]) <= year_range[1])
        ]
    else:
        targeted_dirs = [i for i in source_root.glob("*") if i.is_dir()]
    result = sorted(
        str(i.relative_to(source_root))
        for i in pydash.flatten(j.rglob("*") for j in targeted_dirs)
        if filename_suffix(i.name) in SUFFIXES_VIDEO and i.is_file()
    )
    Path("manual_data").mkdir(exist_ok=True)
    Path("manual_data/video_list.txt").write_text("\n".join(result), "utf-8")


# ================可以在调试终端上运行的部分================
# ========数字区========
PATTERN_CHINUM = re.compile(
    r"(?:(?:([前后後上中下])|第([一二三四五六七八九十0-9]{1,2}))[话話卷巻编編章])|([一二三四五六七八九十0-9]{1,2})日目"
)
PATTERN_NUM = re.compile(
    r"#\d+|＃\d+|Vol.\d+|\d+(?:st|nd|rd|th)|-Episode\d+-|ACT\.\d+|\d+$",
    re.IGNORECASE,
)


# ========文本处理区========
TITLE_LEN_MIN = 5
PATTERN_JUNK_TAG = re.compile(r"The Animation|Anime Edition|OVA", re.IGNORECASE)
PATTERN_JUNK_TAIL = re.compile(r"[…。！？!?＃♪↑]+$")


def filename_purified_hanime(path: PurePath) -> str:
    # 这里的stem可以根据“stem.chs.mp4”得到“stem.chs”
    text = re.sub(r"\.(?:chs|cht|raw)$", "", filename_stem(path.name))
    # 表示发行公司和日期的元数据用的方括号
    text = re.sub(r"\[.+?\]|", "", text)
    # 主标题中的各种方括号
    text = re.sub(r"[\[「［].+?[\]］」]", "", text)
    # 不标准的副标题
    text = re.sub(r"‐", "～", text)
    # 主标题和副标题分开
    text = re.sub(r"(～.+?～)", r" \1 ", text)
    # 分隔符统一为空格
    text = re.sub(r"\s+|_+|-+", " ", text)
    # 无效字符，影响搜索
    text = text.replace("×", "x")
    text = PATTERN_JUNK_TAG.sub("", text)
    # ========去掉数字========
    text = PATTERN_NUM.split(text)[0].strip()
    text = PATTERN_CHINUM.split(text)[0].strip()
    # ========识别主标题========
    # 拆分标题和"～.+?～"表示的副标题
    matched = re.search(r"(.+) (～.+?～)", text)
    text, _ = matched.groups() if matched else (text, "")
    if not re.match(r"^[a-zA-Z0-9_ '&-]+$", text):
        # 纯英文的标题保留全部内容
        # 其他标题根据被空格分隔的第一段的长度判断名称
        splitted = text.strip().split(" ")
        text = splitted[0] if len(re.sub(r"\d+$", "", splitted[0])) >= TITLE_LEN_MIN else " ".join(splitted[:2]).strip()
    text = PATTERN_JUNK_TAIL.sub("", text)
    return text


# ========排序和归纳区========
def get_dict_with_purified_name(video_list):
    result = {}
    for video in video_list:
        key = filename_purified_hanime(video)
        result.setdefault(key, []).append((datetime_from_filepath(video.parts[1]), video))
    for key, videoobjs in result.items():
        files = sorted(videoobjs, key=lambda j: j[0])
        result[key] = files
    return result


def output_csv_for_manual():
    video_list = Path("manual_data/video_list.txt").read_text("utf-8").split("\n")
    video_list = [PurePath(i) for i in video_list]
    dict_with_purified_name = get_dict_with_purified_name(video_list)
    result = [["bgmtvid", "key", "month", "sort_in_month", "SP_index", "raw_name"]]
    for k, videoobjs in dict_with_purified_name.items():
        for date, videoobj in videoobjs:
            result.append(["", k, date, "1", "", videoobj.name])
    write_csv(Path("manual_data/refer_id_for_manual.csv"), result)


if __name__ == "__main__":
    if DEBUG:
        output_csv_for_manual()
    else:
        # argv为 module_name {source_root} {start_year} {end_year}
        if len(argv) == 2:
            year_range = ()
        elif len(argv) == 3:
            year_range = (int(argv[2]), int(argv[2]))
        else:
            year_range = (int(argv[2]), int(argv[3]))
        output_video_list(Path(argv[1]).resolve(), year_range)
        try:
            output_csv_for_manual()
        except:
            print("生成“manual_data/refer_id_for_manual.csv”时出错")
